#ifndef _EVENT_H_
#define _EVENT_H_

#include <reactor.h>


#define EV_READ_INT      0
#define EV_WRITE_INT     1
#define EV_SIGNAL_INT    2
#define EV_CONNECT_INT   3
#define EV_ACCEPT_INT    4
#define EV_BREAK_INT     28
#define EV_ERR_INT       29
#define EV_FORCE_OFF_INT 30
#define EV_SLEEP_INT     31

#define EV_READ         (1 << EV_READ_INT)
#define EV_WRITE        (1 << EV_WRITE_INT)
#define EV_SIGNAL       (1 << EV_SIGNAL_INT)
#define EV_CONNECT      (1 << EV_CONNECT_INT)
#define EV_ACCEPT       (1 << EV_ACCEPT_INT)
#define EV_BREAK        (1 << EV_BREAK_INT)
#define EV_ERR          (1 << EV_ERR_INT)
#define EV_FORCE_OFF    (1 << EV_FORCE_OFF_INT)
#define EV_SLEEP        (1 << EV_SLEEP_INT)


struct event;
struct reactor;

struct event {
    int fd ;
    struct reactor *reactor;
    int mode;
    int signal;
    int (*evCallback)(struct *ev, int mode, void *args);

    
    struct event *prev;
    struct event *next;

    int inited;
    int minHeapKey ;    
};

struct eventOps {
    char *name;
    int(*init)(void);
    int(*add)(struct event *);
    int(*mod)(struct event *);
    int(*del)(struct event *);
    int (*run)(struct reactor * _reactor, int timeout);
};

struct reactor{
    struct eventOps * sysOps;
    struct eventList  readyQueue ;
    struct eventList  waitQueue  ;
    struct eventList  signalQueue;
    struct minheap *  minheap    ;
    
    int epoll_fd;

    int readyQueueNum ;
    int waitQueueNum  ;
    int signalQueueNum;

    int cpuNum;

    void (*r_malloc)(unsigned int);
    void (*r_free)(void *);
    void *(*r_realloc)(void *, unsigned int);
};

struct eventList{
    struct event *head;
    struct event *tail;
    int nodeNum;
};

static inline int eventListInit(struct eventList * _L){
    if (_L == (struct eventList*)NULL){
        return -1;
    }
    _L->head    = NULL;
    _L->tail    = _L->head;
    _L->nodeNum = 0;
    return 0;
}

static inline int eventAdd(struct eventList * _L, struct event *_ev){
    if (_L == (struct eventList*)NULL || _ev == (struct event *)NULL ){
        return -1;
    }

    if (_L->head == (struct event *)NULL){
        _L->head = _ev;
        _ev->prev = NULL ;
        _ev->next = NULL ;
    }else{
        _L->tail->next = _ev;
        _ev->prev = _L->tail;
        _ev->next = NULL ;
    }
    _L->tail = _ev;
    _L->nodeNum += 1;
    return 0;
}

static inline int eventRm(struct eventList * _L, struct event *_ev){
    if (_L == (struct eventList*)NULL || _ev == (struct event *)NULL ){
        return -1;
    }
    if(_ev == _L->head){
        if(_ev->next == (struct event *)NULL){
            return eventListInit(_L);
        }else{
            _L->head = _ev->next;
        }
    }else if(_ev == _L->tail){
        if(_ev->prev == (struct event *)NULL){
            return eventListInit(_L);
        }else{
            _L->tail = _ev->prev;
            _L->tail->next = NULL ;
        }
    }
    _ev->prev->next = _ev->next;
    _ev->next->prev = _ev->prev;
    _L->nodeNum -= 1;
    return 0;
}

#endif
